CodeBuild で GitHub の pull request をビルドできるようになりました

CodeBuild で GitHub の pull request をビルドできるようになりました

Clock Icon2017.10.05

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

ども、藤本です。

現地時間 9/27、CodeBuild が GitHub の pull request を対象にビルドできるようになりました。

今回は試してみるとともに標準設定ではできない、自動ビルドを実装してみました。

概要

CodeBuild は CodeCommit、S3、GitHub、BitBucket にあるソースコードをコンパイルしたり、スタイルチェックしたり、ユニットテストしたりできるビルドサービスです。個人的には CodePipeline と組み合わせることでソースコード更新をトリガーに自由にスクリプトを実行できるのでビルドだけに限らず色々なことができる夢のあるサービスだと思っています。

今まで GitHub のソースコードを対象にビルドしようとした場合、ブランチ名、タグ名、コミットID を対象にすることができました。今回のアップデートではプルリクエストID を指定可能になりました。プルリクエストID はpr/xxx(xxx は番号)の形式で指定します。これにより、プルリクエストに対して事前にスタイルチェック NG、ユニットテスト NG を弾くことができ、無駄な確認稼働を割かなくても良くなりました。地味に嬉しいアップデートです。

それでは早速アップデート内容を試してみましょう。

試してみた

事前準備

下記は割愛します。

  • ソースコード作成(今回は公式ドキュメントにある Python のサンプルコードを利用)
  • GitHub リポジトリ作成(今回はpr-codebuildという Public リポジトリを作成)

CodeBuild プロジェクト作成

下記を参考に GitHub をソースとした CodeBuild プロジェクトを作成します。

チュートリアルを通してCodeBuildを理解する #reinvent

プルリク

適当にソースコードを修正してプルリクします。

$ git checkout -b bugfix/typo
Switched to branch 'bugfix/typo'
$ git commit -am "fix typo"
[bugfix/typo 863a3db] fix typo
 2 files changed, 5 insertions(+), 5 deletions(-)
$ git push origin bugfix/typo
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 306 bytes | 306.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To github.com:s-fujimoto/pr-codebuild.git
   863a3db..ed6fdd2  bugfix/typo -> bugfix/typo
$ git pr -m "bugfix typo" # 「hub」コマンドのエイリアス設定しています
https://github.com/s-fujimoto/pr-codebuild/pull/1

プルリクエストの URL の番号が CodeBuild にて指定するプルリクエストID となります。

ビルド開始

CodeBuild に戻って、、、
作成した CodeBuild プロジェクトを選択して、[Start build]をクリックします。[Source version]にプルリクエストIDを指定します。今回はプルリクエストID が1ですので、pr/1を指定します。[Start build]をクリックします。

AWS_CodeBuild_Management

こんな感じでビルドが実行されます。

AWS_CodeBuild_Management 3

自動ビルドの実装

とはいえ、CodePipline が対応しているわけではないので現状プルリクエストが来た時に自動で CodeBuild が実行されるわけではありません。かと言って、プルリクエスト来る度に手動でビルドするのは手間です。なので、自動で走るように実装しましょう。やることは下記となります。そんなに大変ではありません。

  • 処理の流れ
    • Pull Request -> SNS -> Lambda -> CodeBuild
  • やること
    • Lambda 作成
    • SNS Topic/Subscription 作成
    • IAM ユーザー作成
    • GitHub リポジトリの SNS 連携設定
    • GitHub の Hook設定
    • 動作確認

Lambda 作成

今回は Python 3.6 の Lambda を実装します。SNS で受け取ったメッセージからプルリクエストID を引っ張ってきて、CodeBuild の API を叩いてビルド実行するだけです。CodeBuild プロジェクト名は Lambda の環境変数PROJECT_NAMEに指定してください。

import boto3
import os
import json

def handler(event, context):
    project_name = os.environ['PROJECT_NAME']

    for record in event['Records']:
        message = json.loads(record['Sns']['Message'])
        if not message.get('pull_request'):
            return 'event is not pull request'
        pr_id = message['number']
    
        build = boto3.client('codebuild')
        build.start_build(
            projectName = project_name,
            sourceVersion = 'pr/' + str(pr_id)
        )

SNS Topic/Subscription 作成

SNS Topic/Subscription を作成します。Subscription に作成した Lambda Function を指定します。候補表示されるので選択すれば OK です。

IAM ユーザー作成

GitHub から SNS を呼び出すのに IAM ユーザーのアクセスキー、シークレットキーが必要となります。IAM ポリシーは GitHub の SNS 連携設定画面にて必要なポリシー例が表示されますのでそれを参考に設定しましょう。

Add_service

GitHub リポジトリの SNS 連携設定

GitHub へのイベントを SNS にプッシュする連携設定を実施します。対象とする GitHub リポジトリ画面からインテグレーション設定画面へ遷移します。[Add service]を展開し、[Amazon SNS]を検索して、選択します。

Apps_and_integrations

上で作成した IAM ユーザーのアクセスキー、シークレットキー、SNS Topic の ARN、リージョンを指定します。

Add_service 2

GitHub の Hook 設定

標準設定ではpushイベントのみがトリガーとなりますので、pull_requestイベントをトリガーに加えます。今回は合わせてpushイベントのトリガーを削除しています。設定方法か下記エントリをご参照ください。

GitHubのプルリクエストをAmazon SNSに通知する

動作確認

以上で設定完了です。動作確認してみましょう。適当にプルリクエストを作成します。

$ git pr -m "fix test code"
https://github.com/s-fujimoto/pr-codebuild/pull/12

CodeBuild の画面を見てみると Build history を見てみると、、、

AWS_CodeBuild_Management 4

pr/12を対象としたビルドが実行されています!

まとめ

いかがでしたでしょうか? CodeBuild が GitHub のプルリクエストに対応し、また便利に使えるようになりました。願わくは自動連携する機能もできてほしいですね。本当はプルリクエスト(GitHub)側に結果を返す実装もしたかったですが、それは誰かに期待w

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.